mongoDB操作指南

您所在的位置:网站首页 mongodb find aggregate mongoDB操作指南

mongoDB操作指南

#mongoDB操作指南| 来源: 网络整理| 查看: 265

目录1. docker安装mongoDB2. 库-database3. 集合-collection3.1 命名规范3.2 增-createCollection3.3 删-drop4. 文档-document4.1 命名规范4.2 增-insert,insertMany(单个增,批量增)4.2.1 insertOne-单个增4.2.2 insertMany-批量增4.2.3 insert-单个增或批量增4.3 查-find4.3.1 find-查所有,条件查,投影查4.3.2 limit,offset翻页查,排序4.3.3 正则模糊查询(相当于like)4.3.4 大于gt,小于lt,大于等于gte,小于等于lte,不等于ne4.3.5 包含查询-\(in,不包含查询-\)nin4.3.6 条件连接-\(and,\)or4.4 改-update,updateOne4.5 删-remove4.6 统计aggregate聚合函数-count,max,min,avg,sum5. 索引-index5.1 mongo B-tree与mysql B+tree分析5.2 索引分类5.2.1 单字段索引5.2.2 复合索引5.2.3 其他索引-地理空间索引,文本索引,哈希索引5.3 getIndexes-索引查看5.4 createIndex-索引创建5.5 dropIndex-索引删除5.6 explain-执行计划6. golang使用mongoDB6.1 初始化6.2 findOne-查询单个6.3 find-查询所有6.4 InsertOne-单条插入6.4 InsertMany-批量插入16.5 BulkWrite-批量插入26.6 UpdateMany-批量更新6.7 DeleteOne-删除一个6.8 DeleteMany-批量删除

1. docker安装mongoDB docker pull mongo:5.0 docker run -itd --name mongo:5.0 -p 27017:27017 mongo --auth -p 27017:27017 :映射容器服务的 27017 端口到宿主机的 27017 端口。外部可以直接通过 宿主机 ip:27017 访问到 mongo 的服务。 --auth:需要密码才能访问容器服务。 $ docker exec -it mongo mongo admin # 创建一个名为 admin,密码为 123456 的用户。 > db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]}); # 尝试使用上面创建的用户信息进行连接。 > db.auth('admin', '123456') 2. 库-database use 数据库名称 //选择和创建数据库的语法格式 注意:在MongoDB中,集台只有在内容插入后才会创建!就是说,创建集合(数据表)后,必须要再插入一个文档(记录),集合才会真正的创建 db //查看当前正在使用的数据库名称 db.user.getDB() //获取库名 db.version() //获取版本 3. 集合-collection

集合,类似关系型数据库中的表。 可以显示的创建,也可以隐式的创建。

3.1 命名规范 1.集合名不能是空字符串""。 2.集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。 3.集合名不能以"system."开头,这是为系统集合保留的前缀。 4.用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除 非你要访问这种系统创建的集合,否则千万不要在名字里出现$。 3.2 增-createCollection 增: 集合创建(显示创建): db.createCollection("test2") 集合创建(隐士创建): 当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合 注:通常我们使用隐式创建文档即可。 3.3 删-drop 删: db.集合名.drop() db.test2.drop() 注:如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false 4. 文档-document

文档(document)的数据结构和 JSON 基本一样。

所有存储在集合中的数据都是 BSON 格式

4.1 命名规范 1)键不能含有\0 (空字符)。这个字符用来表示键的结尾。 2)"."点和$有特别的意义,只有在特定环境下才能使用。 3)以下划线"_"开头的键是保留的(不是严格要求的)。 4.2 增-insert,insertMany(单个增,批量增) 注: 1.user代表集合名称 2.comment集合如果不存在,则会隐式创建 3.mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。 4.插入当前日期使用 new Date() 5.插入的数据没有指定 _id ,会自动生成主键值 6.如果某字段没值,可以赋值为null,或不写该字段。 7.批量插入如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。所以需要处理异常 4.2.1 insertOne-单个增 单个增: db.user.insertOne([{ "name":"jeff004", "age":18, }]) 4.2.2 insertMany-批量增 批量增: db.user.insertMany([ {"name":"ooo","sex":"男"}, {"name":"xxx","sex":"女"} ]) 结果:acknowledged:true insertedlds:(Array) 2 Elements 4.2.3 insert-单个增或批量增 //批量增 db.user.insert([{ "name":"jeff006", "age":18, }, { "name":"jeff007", "age":18, } ]) //单个增 db.user.insert({ "name":"jeff008", "age":18, }) 4.3 查-find 4.3.1 find-查所有,条件查,投影查 db.user.find() //查询集合所有 db.user.find({name:"123"}); //条件查询 db.user.findOne({name:"123"}); //条件查询,返回符合条件的第一条数据 db.user.find({_id:ObjectId("643622e64a2ad86c86062273")}); //_id查询 //投影查 //如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。 //投影查,1:显示 0:不显示,默认 _id 会显示。 db.user.find({name:"123"},{"name":1}); db.user.find({name:"123"},{name:1,_id:0}); //_id不显示 4.3.2 limit,offset翻页查,排序 //limit限制条数,skip跳过条数 db.user.find().limit(10).skip(2) //排序 db.user.find().sort({age:-1}) //-1降序,1升序 db.user.find().sort({age:-1,userid:1}) //先按age降序,再按userid生序排列 //排序取第一条 db.user.find().sort({age:-1}).limit(1)//max,先排序,再取第一条 db.user.find().sort({age:1}).limit(1) //min,先排序,再取第一条 4.3.3 正则模糊查询(相当于like) db.user.find({name:/正则表达式/}) db.user.find({name:/ef/}) //匹配jeff 4.3.4 大于gt,小于lt,大于等于gte,小于等于lte,不等于ne //大于$gt,小于$lt,大于等于$gte,小于等于$lte,不等于$ne //不等于 db.user.find({name:{$ne:"jeff"}}) //name!=“jeff”的所有 //大于 db.user.find({age:{$gt:5}}) //age大于5的所有 //小于 db.user.find({age:{$lt:100}}) //age小于100的所有 4.3.5 包含查询-\(in,不包含查询-\)nin db.user.find({name:{$in:["jeff","chery"]}}) //user集合中name字段包含的 db.user.find({name:{$nin:["jeff","chery"]}}) ////user集合中name字段不包含的 4.3.6 条件连接-\(and,\)or db.user.find($and:[ { },{ },{ }]) //name=jeff and age=10 db.user.find({$and:[{name:"jeff"},{age:10}]}) //and //name正则匹配 and age>5 db.user.find({$and:[{name:/ef/},{age:{$gt:5}}]}) //and //name="jeff" or age>10 db.user.find({$or:[{name:"jeff"},{age:{$gt:10}}]}) //or 4.4 改-update,updateOne //默认只修改第一条 $set db.user.update({name:"123"},{$set:{name:"jeff"}}) //修改符合条件的所有数据 multi:true db.user.update({name:"123"},{$set:{name:"jeff"}},{multi:true}) //每次原基础上递增10 $inc db.user.update({name:"jeff"},{$inc:{age:10}}) //$max,$min使用 //解释:age大于小于300则修改,否则不修改 db.user.updateOne({name:"jeff"},{$max:{age:300}}) db.user.updateOne({name:"jeff"},{$min:{age:300}}) 4.5 删-remove //删除符合条件所有 db.user.remove({name:"jeff"}) 4.6 统计aggregate聚合函数-count,max,min,avg,sum //count db.user.count() //集合全部计数 db.user.count({name:"jeff"}) //集合条件计数 //avg db.user.aggregate([ { $group : { _id : null, avgAge: { $avg : "$age" } } } ]) //max db.user.aggregate([ { $group : { _id : null, avgAge: { $max : "$age" } } } ]) //min db.user.aggregate([ { $group : { _id : null, avgAge: { $min : "$age" } } } ]) //sum db.user.aggregate([ { $group : { _id : null, avgAge: { $sum : "$age" } } } ]) 5. 索引-index 5.1 mongo B-tree与mysql B+tree分析 mongo索引结构:B-Tree mysql索引结构:B+Tree B-Tree与B+Tree区别:B+tree只有叶子结点存数据,B-Tree所有节点都存数据 原因:mongo与mysql使用场景不一样,mysql是关系型,mongo是非关系性 至于为什么MongoDB使用B树而不是B +树,可以从其设计的角度考虑它。 MongoDB不是传统的关系数据库,而是以BSON格式(可以认为是JSON)存储的nosql。目的是高性能,高可用性和易于扩展。 Mysql是关系型数据库,最常用的是数据遍历操作(join),而MongoDB它的数据更多的是聚合过的数据,不像Mysql那样表之间的关系那么强烈,因此MongoDB更多的是单个查询。 由于Mysql使用B+树,数据在叶节点上,叶子节点之间又通过双向链表连接,更加有利于数据遍历,而MongoDB使用B树,所有节点都有一个数据字段。只要找到指定的索引,就可以对其进行访问。毫无疑问,单个查询MongoDB平均查询速度比Mysql快。 5.2 索引分类 5.2.1 单字段索引

MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。 对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。

img

5.2.2 复合索引

MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。

复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后 在每个userid的值内,再在按score倒序排序。

img

5.2.3 其他索引-地理空间索引,文本索引,哈希索引

地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。

为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面 几何的二维球面索引。

img

5.3 getIndexes-索引查看 db.user.getIndexes() //查看索引 [ { "v" : 2, # mongodb引擎的版本号(不用管) "key" : { "_id" : 1 # 默认主键 }, "name" : "_id_", # 索引名称 "ns" : "jeff.comment" # 索引的位置 } ] 5.4 createIndex-索引创建 db.集合名.createIndex(keys, options) //升序普通索引 db.user.createIndex({userid:1}) //1升序索引,-1降序索引 db.user.createIndex({name:1},{unique:true}) //新,推荐 db.user.ensureIndex({name:1},{unique:true}) //老,不推荐,3.0.0版本前,createIndex的别名 //复合索引 db.user.createIndex({userid:1,name:-1}) //先userid升序,再name降序

options参数列表:

options(更多选项)列表:

Parameter Type Description background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。"background" 默认值为false。 unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名 称。 dropDups Boolean 3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索 引字段中不会查询出不包含对应字段的文档.。默认值为 false. expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

提示: 注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex() ,之后的版本使用了 db.collection.createIndex() 方法, ensureIndex() 还能用,但只是 createIndex() 的别名。

5.5 dropIndex-索引删除 db.集合名.dropIndex(索引) //指定删除:删除{userid:1}索引 db.user.dropIndex({userid:1}) //全部删除:删除集合全部索引,除_id索引 db.user.dropIndexes() 5.6 explain-执行计划

分析查询性能 通常使用执行计划来查看查询的情况,如查询耗费的时间、是 否基于索引查询等。 那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看。

db.集合名.find(query,options).explain(options) //eg: db.user.find({"name":"jeff"}).explain() 6. golang使用mongoDB 6.1 初始化 import ( "context" "encoding/json" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "log" ) var Client *mongo.Client func initMongo(url string) error { clientOptions := options.Client().ApplyURI(url) client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } // 检测连接 err = client.Ping(context.TODO(), nil) if err != nil { fmt.Println("连接失败!err:", err) return err } fmt.Println("Connected to MongoDB!") Client = client return nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } } 6.2 findOne-查询单个 //查询单个 func findOne(detection_coll *mongo.Collection, filter bson.D) (result map[string]interface{}, err error) { err = detection_coll.FindOne(context.TODO(), filter).Decode(&result) if err != nil { fmt.Println(err) return nil, err } return } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") // 查询单条数据 type User struct { Id string `json:"_id"` Age int `json:"age"` Name string `json:"name"` } user := User{} //查询单个 filter := bson.D{{Key: "name", Value: "jeff"}} data, err := findOne(detection_coll, filter) if err != nil { fmt.Println(err) return } fmt.Println(data) bStr, _ := json.Marshal(data) _ = json.Unmarshal(bStr, &user) fmt.Println(user) } 6.3 find-查询所有 import ( "context" "fmt" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "log" ) type User struct { Id string `json:"_id"` Age int `json:"age"` Name string `json:"name"` } //查询所有 func find(detection_coll *mongo.Collection, filter bson.D, reslist []*User) (reqlist []*User, err error) { cur, err := detection_coll.Find(context.TODO(), filter) if err != nil { return nil, err } if err = cur.Err(); err != nil { return nil, err } err = cur.All(context.Background(), &reslist) if err != nil { return nil, err } _ = cur.Close(context.Background()) return reslist, nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") userList := []*User{} //查询所有 filter := bson.D{{Key: "age", Value: 18}} list, err := find(detection_coll, filter, userList) if err != nil { fmt.Println(err) return } fmt.Println(list) for _, one := range list { fmt.Println(one) } } 6.4 InsertOne-单条插入 //单条插入 func InsertOne(detection_coll *mongo.Collection, info interface{}) (objectID interface{}, err error) { objId, err := detection_coll.InsertOne(context.TODO(), info) if err != nil { return nil, err } fmt.Println("_id:", objId.InsertedID) return objId, nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") userInfo := User{ Name: "jeff002", Age: 20, } objectID, err := InsertOne(detection_coll, userInfo) if err != nil { fmt.Println(err) return } fmt.Println(objectID) } 6.4 InsertMany-批量插入1 //批量插入 func InsertMany(detection_coll *mongo.Collection, infolist []interface{}) (count int, err error) { objId, err := detection_coll.InsertMany(context.TODO(), infolist) if err != nil { return 0, err } return len(objId.InsertedIDs), nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") userInfo1 := User{ Name: "jeff001", Age: 20, } userInfo2 := User{ Name: "jeff002", Age: 20, } userList := []User{userInfo1, userInfo2} list := []interface{}{} bStr, _ := json.Marshal(userList) _ = json.Unmarshal(bStr, &list) count, err := InsertMany(detection_coll, list) if err != nil { fmt.Println(err) return } fmt.Println(count) } 6.5 BulkWrite-批量插入2 //批量插入 func batchSave(detection_coll *mongo.Collection, models []mongo.WriteModel) (insertedCount int64, err error) { opts := options.BulkWrite().SetOrdered(false) res, err := detection_coll.BulkWrite(context.TODO(), models, opts) if err != nil { return 0, err } return res.InsertedCount, nil } type User struct { Age int `json:"age"` Name string `json:"name"` } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") userInfo1 := User{ Name: "jeff003", Age: 20, } userInfo2 := User{ Name: "jeff004", Age: 20, } models := []mongo.WriteModel{ mongo.NewInsertOneModel().SetDocument(userInfo1), mongo.NewInsertOneModel().SetDocument(userInfo2), } count, err := batchSave(detection_coll, models) if err != nil { fmt.Println(err) return } fmt.Println(count) } 6.6 UpdateMany-批量更新 //批量更新 func updateMany(detection_coll *mongo.Collection, filter, updateData interface{}) (matchedCount, modifiedCount int64, err error) { result, err := detection_coll.UpdateMany(context.TODO(), filter, updateData) if err != nil { return 0, 0, err } //matchedCount匹配数 //modifiedCount修改数 return result.MatchedCount, result.ModifiedCount, nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") detectionIds := []string{"jeff001", "jeff002"} filter := bson.D{{Key: "name", Value: bson.D{{Key: "$in", Value: detectionIds}}}} // filter := bson.D{{Key: "name", Value: "jeff001"}} //条件 update := bson.D{ {Key: "$set", Value: bson.D{ {Key: "age", Value: 89}, }}, } matchedCount, modifiedCount, err := updateMany(detection_coll, filter, update) if err != nil { fmt.Println(err) return } fmt.Println("匹配数:", matchedCount) fmt.Println("修改数:", modifiedCount) } 6.7 DeleteOne-删除一个 //删除一个 func deleteOne(detection_coll *mongo.Collection, filter interface{}) (deletedCount int64, err error) { result, err := detection_coll.DeleteOne(context.TODO(), filter) if err != nil { return 0, err } return result.DeletedCount, nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") detectionIds := []string{"jeff001", "jeff002"} filter := bson.D{{Key: "name", Value: bson.D{{Key: "$in", Value: detectionIds}}}} deletedCount, err := deleteOne(detection_coll, filter) if err != nil { fmt.Println(err) return } fmt.Println("删除数量:", deletedCount) } 6.8 DeleteMany-批量删除 //批量删除 func deleteOne(detection_coll *mongo.Collection, filter interface{}) (deletedCount int64, err error) { result, err := detection_coll.DeleteMany(context.TODO(), filter) if err != nil { return 0, err } return result.DeletedCount, nil } func main() { url := "mongodb://admin:[email protected]:27017" //初始化 if err := initMongo(url); err != nil { fmt.Println("连接失败!err:", err) return } // 获取collection detection_coll := Client.Database("test").Collection("user") detectionIds := []string{"jeff001", "jeff002"} filter := bson.D{{Key: "name", Value: bson.D{{Key: "$in", Value: detectionIds}}}} deletedCount, err := deleteOne(detection_coll, filter) if err != nil { fmt.Println(err) return } fmt.Println("删除数量:", deletedCount) }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3